﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using DomainModel.Entities;
using Service.Abstract;

namespace WebUI.Controllers
{
    [Authorize]
    public class TaskController : BaseController
    {
        private readonly IUserService _userService;
        private readonly ITaskService _taskService;
        private readonly IProjectService _projectService;

        public TaskController(IUserService userService, IProjectService projectService, ITaskService taskService)
            : base(userService)
        {
            _userService = userService;
            _taskService = taskService;
            _projectService = projectService;
        }

        private IEnumerable<SelectListItem> Projects()
        {
            var projects = _projectService.GetAllByUserId(CurrentUser.UserId);
            IEnumerable<SelectListItem> selectList =
                from project in projects
                select new SelectListItem
                {
                    Text = project.Name,
                    Value = project.Id.ToString()
                };
            return selectList;
        }

        private IList<SelectListItem> ProjectsSelectList(int? projectId)
        {
            var projects = new List<SelectListItem>();
            projects.Add(new SelectListItem { Value = "0", Text = "Choose..." });

            foreach (var item in _projectService.GetAllByUserId(CurrentUser.UserId))
            {
                var listitem = new SelectListItem() {Text = item.Name, Value = item.Id.ToString()};
                if(projectId == item.Id)
                {
                    listitem.Selected = true;

                }
                projects.Add(listitem);
            }

            return projects;
        }

        #region Inbox view

        public ActionResult Inbox()
        {
            var model = _taskService.GetAllByUserId(CurrentUser.UserId).Where(x => x.ProjectId == 0 || x.ProjectId == null);
            ViewData["TabTitle"] = "Inbox";
            return PartialView("TaskListWithTab", model);
        }

        public ActionResult AllTask()
        {
            var model = _projectService.GetAllByUserId(CurrentUser.UserId);
            return PartialView("Task/AllTaskView", model);
        }

        public ActionResult TaskByProjectId(int projectId)
        {
            var model = _taskService.GetTasksByProject(CurrentUser, projectId);
            ViewData["TabTitle"] = _projectService.GetProjectById(projectId).Name;
            return PartialView("TaskListWithTab", model);
        }

        #endregion

        #region Upcoming List
        public ActionResult UpcomingList()
        {
            return PartialView("Task/UpcomingTaskList");
        }

        public ActionResult UpcomingListByDate(int dateSpan1, int dateSpan2, string tabTitle)
        {
            var model = _taskService.GetTasksByDate(CurrentUser, dateSpan1, dateSpan2).OrderBy(x => x.DateDue);
            ViewData["TabTitle"] = tabTitle;
            return PartialView("TaskListWithTab", model);
        }

        #endregion
        
        public ActionResult FlaggedTask()
        {
            return PartialView("TaskList", _taskService.GetAllByUserId(CurrentUser.UserId).Where(x => x.Flagged));
        }
       
        public ActionResult InboxView()
        {
            var model = _taskService.GetAllByUserId(CurrentUser.UserId).Where(x => x.ProjectId == 0 || x.ProjectId == null);
            return PartialView("TaskList", model);
        }

        public ActionResult TasksList()
        {
            ViewData["selectList"] = Projects();
            return View("TaskList", _taskService.GetAllByUserId(CurrentUser.UserId));
        }

        public ActionResult TasksListByProject(int projectId)
        {
            ViewData["selectList"] = Projects();

            if (Request.IsAjaxRequest())
                return View("TaskList", _taskService.GetTasksByProject(CurrentUser, projectId));

            return View("TaskList", _taskService.GetTasksByProject(CurrentUser, projectId));
        }

        [AcceptVerbs(HttpVerbs.Get)]
        public ActionResult AddTask(int? projectId)
        {
            ViewData["Projects"] = ProjectsSelectList(projectId);
            var model = new Task{DateDue = null};
            return PartialView("Task/AddTask", model);
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult AddTask(Task model)
        {
            if(model.Name != null)
            {
                _taskService.Add(model, CurrentUser.UserId);

                ViewData["InsertMode"] = "inlist";

                if (Request.IsAjaxRequest())
                    return View("TaskSummary", model);                
            }
            return null;
        }

        [AcceptVerbs(HttpVerbs.Get)]
        public ActionResult EditTask(int id)
        {
            var task = _taskService.GetTaskById(id);
            ViewData["Projects"] = ProjectsSelectList(null);
            return PartialView("Task/EditTask", task);
        }
        
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult EditTask(Task model)
        {
            var task = _taskService.GetTaskById(model.Id);

            if (model.Name != null)
            {
                task.Name = model.Name;
                task.ProjectId = model.ProjectId;
                task.Description = model.Description;
                task.DateDue = model.DateDue;
                _taskService.Save(task, CurrentUser.UserId);
                
                ViewData["InsertMode"] = "inlist";
                return PartialView("TaskSummary", task);
            }

            return null;
        }

        public void ClearDone(int[] postData)
        {
            for (int i = 0; i < postData.Count(); i++)
            {
                _taskService.Delete(_taskService.GetTaskById(postData[i]));
            }
        }

        public void DeleteTask(int id)
        {
            _taskService.Delete(_taskService.GetTaskById(id));
        }

        public ActionResult ShowTask(int id)
        {
            return View("ShowTask", _taskService.GetTaskById(id));
        }

        public ActionResult TaskComplete(int id)
        {
            var task = _taskService.GetTaskById(id);
            task.IsComplete = !task.IsComplete;

            _taskService.Save(task, CurrentUser.UserId);

            if (Request.IsAjaxRequest())
                return View("TaskSummary", task);

            return View("TasksList");
        }

        public ActionResult FlagTask(int taskId)
        {
            var task = _taskService.GetTaskById(taskId);
            task.Flagged = !task.Flagged;
            _taskService.Save(task, CurrentUser.UserId);
            ViewData["InsertMode"] = "inlist";
            return PartialView("TaskSummary", task);
        }

        public string GetDateStatus(DateTime date)
        {
            var currentDate = new DateTime(date.Year, date.Month, date.Day);
            var timeSpan = currentDate - DateTime.Today;

            if (timeSpan.Days < 0)
            {
                return "overdue";
            }

            if (timeSpan.Days == 0)
            {
                return "today";
            }

            return string.Empty;
        }

        public string GetDateTitle(DateTime date)
        {
            var currentDate = new DateTime(date.Year, date.Month, date.Day);
            var timeSpan = currentDate - DateTime.Today;

            if(timeSpan.Days == -1)
            {
                return "Yesterday";
            }

            if(timeSpan.Days == 0)
            {
                return "Today";
            }
            
            if(timeSpan.Days == 1)
            {
                return "Tomorrow";
            }

            if(timeSpan.Days > 1 && timeSpan.Days <= 7)
            {
                return date.DayOfWeek.ToString();
            }

            return date.ToString("dd MMM");
        }
    }
}

